package com.tyjt.common;

public class GridUtil {

    private static final double EARTH_RADIUS_KM = 6371.0; // 地球半径（km）
    //  这里以北京天安门城楼中心作为坐标原点
    //  116.39145, 39.90733

    public static GridInfo calcGridInfo(double longitude ,double latitude ){
        double[] doubles = calculateLatLonDistance( longitude,latitude, Constants.TIAN_AN_MEN_LON,Constants.TIAN_AN_MEN_LAT);
        double unit = 1000D/Constants.GRID_CELL_LEN;
        int gridX = (int) (doubles[0]* unit);
        int gridY = (int) (doubles[1]* unit);
        return new GridInfo(gridX,gridY);
    }

    /**
     * 计算两个经纬度点之间的纬度距离和经度距离
     * 此方法适用于几百公里内的距离计算
     * @param lat1 点1纬度
     * @param lon1 点1经度
     * @param centerLat 点2纬度
     * @param centerLon 点2经度
     * @return 数组 [经度距离,纬度距离]（单位：km）
     */
    public static double[] calculateLatLonDistance(double lon1,double lat1, double centerLon,  double centerLat) {
        // 1. 计算纬度距离（南北方向）
        double latDistance = Math.abs(centerLat - lat1) * 111.32;

        // 2. 计算经度距离（东西方向）
        double lonDiff = Math.abs(centerLon - lon1);
        double avgLatRad = Math.toRadians((lat1 + centerLat) / 2);
        double lonDistance = lonDiff * 111.32 * Math.cos(avgLatRad);

        return new double[]{lonDistance, latDistance};
    }

     /**
      * 使用 Haversine（球面距离） 公式计算两个经纬度之间的距离
      * @param lon1 点1经度
      * @param lat1 点1纬度
      * @param lon2 点2经度
      * @param lat2 点2纬度
      * @return 距离（单位：m）
      * */
     public static double haversineDistance(double lon1, double lat1, double lon2, double lat2) {
         // 将经纬度从度转换为弧度
         double lat1Rad = Math.toRadians(lat1);
         double lon1Rad = Math.toRadians(lon1);
         double lat2Rad = Math.toRadians(lat2);
         double lon2Rad = Math.toRadians(lon2);

         // 计算纬度和经度的差值
         double dLat = lat2Rad - lat1Rad;
         double dLon = lon2Rad - lon1Rad;

         // Haversine 公式计算
         double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                 Math.cos(lat1Rad) * Math.cos(lat2Rad) *
                         Math.sin(dLon / 2) * Math.sin(dLon / 2);
         double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

        return EARTH_RADIUS_KM * c *1000;
    }
}
